/*:
* @plugindesc 枫之舞功能 - 传送到去过的城镇（乘龙念法/祠符）
* @author 老饕（参考CP_TownScroll by cnda2010）
* @version 1.0.0
* @date 2020.3.7
* 
* @help
* 本插件用于返回去过的城镇：
* =================================================================
* 1. 设置参数
* ---Base Options---
* （1）Portal Animation1、Town Portal Animation2可分别配置传送前后的动画。
* （2）Town Portal Timeout 用于设置等待第一个动画播放时的时间。
* （3）Town Portal Fade Type 用于设置传送时的过渡方式。
* ---Destination List---
* （1）可配置所有可返回的目的地的名称、地图ID及坐标，最多50个。
* 
* 
* 2. 其它设置
* （1）【物品/技能配置】
*      在物品/技能注释中配置<Historical Town Portal>
*      则此物品/技能自动具有传送到去过的城镇功能，
*      此时该物品的一切其他功能均失效。
* （2）【解锁目的地】
*      在地图注释中配置<Unlock Portal: x>
*      则到过此地图后自动解锁Destination List中的第x项。
* （3）【是否可用判定】
*      在地图注释中配置<Can Historical Portal>
*      设定该地图是否可使用该技能或道具。
*      （《轩辕剑外传 枫之舞》中该技能只能在大地图使用）
* （4）【改变是否可用】
*      使用插件指令：
*      EnableHistoricalPortal	可用
*      DisableHistoricalPortal	禁用


* @param ---Base Options---
* @default
* 
* @param Town Portal Animation1
* @parent ---Base Options---
* @type animation
* @desc 开始传送动画
* @default 1
*
* @param Town Portal Animation2
* @parent ---Base Options---
* @type animation
* @desc 结束传送动画
* @default 1
*
* @param Town Portal Timeout
* @parent ---Base Options---
* @type number
* @min 0
* @desc 留给传送动画的播放时间【单位：毫秒】，根据开始动画的长度设定为佳。默认值：2000
* @default 2000
*
* @param Town Portal Fade Type
* @parent ---Base Options---
* @type select
* @option 变黑
* @value 0
* @option 变白
* @value 1
* @option 无
* @value 2
* @desc 传送时的淡入淡出模式
* @default 0


 * @param ---Destination List---
 * @default
 *
 * @param Destination 1
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 2
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 3
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 4
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 5
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 6
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 7
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 8
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 9
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 10
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 11
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 12
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 13
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 14
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 15
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 16
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 17
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 18
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 19
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 20
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 21
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 22
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 23
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 24
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 25
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 26
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 27
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 28
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 29
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 30
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 31
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 32
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 33
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 34
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 35
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 36
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 37
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 38
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 39
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 40
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 41
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 42
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 43
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 44
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 45
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 46
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 47
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 48
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 49
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 * @param Destination 50
 * @parent ---Destination List---
 * @type struct<Destination>
 * @desc 传送目的地信息接口
 * @default
 *
 
*/
 

/*~struct~Destination:
 *
 * @param Name
 * @desc 传送地点名称（显示在菜单中）.
 * @default
 *
 * @param MapID
 * @desc 传送到地图ID.
 * @default
 *
 * @param x
 * @desc 传送到x坐标.
 * @default
 *
 * @param y
 * @desc 传送到y坐标.
 * @default
 */



var SWDA_HistoricalTownPortal = SWDA_HistoricalTownPortal || {};
var parameters = PluginManager.parameters("SWDA_HistoricalTownPortal");

SWDA_HistoricalTownPortal.destinationData = [];
SWDA_HistoricalTownPortal.destinationUnlocked = [];
for (var i = 1; i <= 50; ++i) {
	SWDA_HistoricalTownPortal.destinationData.push(JSON.parse(parameters['Destination ' + i] || 'null'));
	SWDA_HistoricalTownPortal.destinationUnlocked.push(false);
};

SWDA_HistoricalTownPortal.TOWN_PORTAL_ANIMATION1 = Number(parameters["Town Portal Animation1"]) || 1;
SWDA_HistoricalTownPortal.TOWN_PORTAL_ANIMATION2 = Number(parameters["Town Portal Animation2"]) || 1;
SWDA_HistoricalTownPortal.TOWN_PORTAL_TIMEOUT = Number(parameters["Town Portal Timeout"]) || 2000;
SWDA_HistoricalTownPortal.TOWN_PORTAL_FADE_TYPE = Number(parameters["Town Portal Fade Type"]) || 0;


//=============================================================================
// 回城数据类型定义
//=============================================================================
//道具技能设定部分
//1. 判定是否为传送
DataManager.isHistoricalTownPortal = function(item){
	if(!item)
		return false;
	if(item.meta["Historical Town Portal"]){
		return true;}
	else
		return false;
};
//=============================================================================
// 回城数据类型定义
//=============================================================================

function DestinationLocation(mapId, mapX, mapY){
	this.initialize(mapId, mapX, mapY);
};

DestinationLocation.prototype.initialize = function(mapId, mapX, mapY){
	this._mapId = mapId;
	this._mapX = mapX;
	this._mapY = mapY;
};

DestinationLocation.prototype.mapId = function(){
	return this._mapId;
};

DestinationLocation.prototype.mapX = function(){
	return this._mapX;
};

DestinationLocation.prototype.mapY = function(){
	return this._mapY;
};

//=============================================================================
// 解锁目的地
//=============================================================================

SWDA_HistoricalTownPortal.IS_MAP_LOADED = DataManager.isMapLoaded;
DataManager.isMapLoaded = function() {
    var loaded = SWDA_HistoricalTownPortal.IS_MAP_LOADED.call(this);
    if(!loaded)
		return loaded;

    SWDA_HistoricalTownPortal.loadHistoricalTownPortalData();
    return loaded;
};

SWDA_HistoricalTownPortal.loadHistoricalTownPortalData = function(){
	var map = $dataMap;
	if(!map)
		return;
	if($testEvent)
		return;

	var reg = /<Unlock Portal: (\d*)>/;
	reg.exec(map.note);

	var unlockedPortalId = Number(RegExp.$1) || 0;
	SWDA_HistoricalTownPortal.destinationUnlocked[unlockedPortalId - 1] = true;
};

//=============================================================================
// 道具使用(Scene_ItemBase)
//=============================================================================

//2. 处理使用
SWDA_HistoricalTownPortal.DETERMINE_ITEM = Scene_ItemBase.prototype.determineItem;
Scene_ItemBase.prototype.determineItem = function() {
    if(DataManager.isHistoricalTownPortal(this.item())){
    	SceneManager.push(Scene_HistoricalTownPortal);
		SWDA_HistoricalTownPortal.user = this.user();
		SWDA_HistoricalTownPortal.item = this.item();
    }else{
    	SWDA_HistoricalTownPortal.DETERMINE_ITEM.call(this);
	}
};


//=============================================================================
// Window_DestinationList 传送系统界面
//=============================================================================

function Window_DestinationList() {
    this.initialize.apply(this, arguments);
}

Window_DestinationList.prototype = Object.create(Window_Command.prototype);
Window_DestinationList.prototype.constructor = Window_DestinationList;

Window_DestinationList.prototype.initialize = function(helpWindow) {
  this._helpWindow = helpWindow;
  Window_Command.prototype.initialize.call(this, 0, helpWindow.height);
  this.setHelpWindow(helpWindow);
};

Window_DestinationList.prototype.windowWidth = function() {
  return Graphics.boxWidth;
};

Window_DestinationList.prototype.windowHeight = function() {
  return Graphics.boxHeight - this._helpWindow.height;
};

Window_DestinationList.prototype.makeCommandList = function() {
	var array = SWDA_HistoricalTownPortal.destinationData;
	var length = array.length;
	for (var i = 0; i < length; ++i) {
		if (SWDA_HistoricalTownPortal.destinationUnlocked[i]){
			var data = array[i];
			var ext = {
				name: data.Name,
				mapid: data.MapID,
				x: data.x,
				y: data.y,
			}
			var enabled = true;
			this.addCommand(data.Name, 'portal', enabled, ext);
		}
	}
};


Window_DestinationList.prototype.drawItem = function(index) {
  var rect = this.itemRectForText(index);
  var align = this.itemTextAlign();
  this.resetTextColor();
  this.changePaintOpacity(this.isCommandEnabled(index));
  var name = this.commandName(index);
  this.drawText(name, rect.x, rect.y, rect.width, align);
};

Window_DestinationList.prototype.updateHelp = function() {
	    if (this._helpWindow) {
        this._helpWindow.setText('请选择目的地。');
    }
};



//=============================================================================
// Scene_HistoricalTownPortal 传送系统界面
//=============================================================================

function Scene_HistoricalTownPortal() {
  this.initialize.apply(this, arguments);
}

Scene_HistoricalTownPortal.prototype = Object.create(Scene_MenuBase.prototype);
Scene_HistoricalTownPortal.prototype.constructor = Scene_HistoricalTownPortal;

Scene_HistoricalTownPortal.prototype.initialize = function() {
  Scene_MenuBase.prototype.initialize.call(this);
};

Scene_HistoricalTownPortal.prototype.create = function() {
  Scene_MenuBase.prototype.create.call(this);
  this.createHelpWindow();
  this.createDestinationListWindow();
};


Scene_HistoricalTownPortal.prototype.createDestinationListWindow = function() {
  this._destinationListWindow = new Window_DestinationList(this._helpWindow);
  this.addWindow(this._destinationListWindow);
  this._destinationListWindow.setHandler('cancel', this.exitScene.bind(this));
  this._destinationListWindow.setHandler('portal', this.Portal.bind(this));
};

// 执行场景传送
Scene_HistoricalTownPortal.prototype.Portal = function() {
	var Destination = this._destinationListWindow.currentExt();
	this._destinationListWindow.activate();
	var destinationLocation = new DestinationLocation(Number(Destination.mapid),Number(Destination.x),Number(Destination.y));
	if(!destinationLocation)
		return;
	this.payHistoricalTownPortalCost();
	$gamePlayer.startHistoricalTownPortal();
	this.executeHistoricalTownPortal(destinationLocation);
	
};

Scene_HistoricalTownPortal.prototype.exitScene = function() {
  this.popScene();
};


//传送动画
SWDA_HistoricalTownPortal.playStartHistoricalTownPortalAnimation = function(){
	$gamePlayer._animationId = SWDA_HistoricalTownPortal.TOWN_PORTAL_ANIMATION1;
};

SWDA_HistoricalTownPortal.playEndHistoricalTownPortalAnimation = function(){
	$gamePlayer._animationId = SWDA_HistoricalTownPortal.TOWN_PORTAL_ANIMATION2;
};

//3.2 执行传送
Scene_HistoricalTownPortal.prototype.executeHistoricalTownPortal = function(destinationLocation){
	//3.2.1 播放动画
	SceneManager.goto(Scene_Map);
	$gamePlayer.gatherFollowers();
	SWDA_HistoricalTownPortal.playStartHistoricalTownPortalAnimation();

	//3.2.3 传送开始	
	setTimeout(function(destinationLocation){
		var mapId = destinationLocation.mapId();
		var x = destinationLocation.mapX();
		var y = destinationLocation.mapY();
		$gamePlayer.reserveTransfer(mapId, x, y, 0, SWDA_HistoricalTownPortal.TOWN_PORTAL_FADE_TYPE);
	}, SWDA_HistoricalTownPortal.TOWN_PORTAL_TIMEOUT, destinationLocation);
};

//3.1 执行消耗

Scene_HistoricalTownPortal.prototype.payHistoricalTownPortalCost = function(){
	
	var user = SWDA_HistoricalTownPortal.user;
	var item = SWDA_HistoricalTownPortal.item;
	if(DataManager.isItem(item)){
		SoundManager.playUseItem();
		user.consumeItem(item);
	}

	if(DataManager.isSkill(item)){
		SoundManager.playUseSkill();
		user.paySkillCost(item);
	}
};




//=============================================================================
// Game_Player（与CP相同）
//=============================================================================
//4. 处理事后
//4.1 玩家封装一个标记，确定是否为回城传送
SWDA_HistoricalTownPortal.INIT_PLAYER = Game_Player.prototype.initialize;
Game_Player.prototype.initialize = function() {
    SWDA_HistoricalTownPortal.INIT_PLAYER.call(this);

    this._historicalTownPortal = false;//封装使用回城标记，隶属于【4.1】
    this._enableHistoricalTownPortal = true;//允许传送的标记，隶属于【5.1】
};

Game_Player.prototype.isHistoricalTownPortal = function(){
	return this._historicalTownPortal;
};

Game_Player.prototype.startHistoricalTownPortal = function(){
	this._historicalTownPortal = true;
};

Game_Player.prototype.endHistoricalTownPortal = function(){
	this._historicalTownPortal = false;
};

//4.2 执行传送后动画
SWDA_HistoricalTownPortal.PERFORM_TRANSFER = Game_Player.prototype.performTransfer;
Game_Player.prototype.performTransfer = function() {
    SWDA_HistoricalTownPortal.PERFORM_TRANSFER.call(this);

    if(this.isHistoricalTownPortal()){
    	SWDA_HistoricalTownPortal.playEndHistoricalTownPortalAnimation();
    	setTimeout(function(player){
    		player.endHistoricalTownPortal();
    	}, SWDA_HistoricalTownPortal.TOWN_PORTAL_TIMEOUT, this);
    }
};


//=============================================================================
// 5. 回城技能道具使用条件以及禁止回城模式
//=============================================================================

//5.1 禁止传送模式标记
Game_Player.prototype.canHistoricalTownPortal = function(){
	return this._enableHistoricalTownPortal;
};

Game_Player.prototype.enableHistoricalTownPortal = function(){
	this._enableHistoricalTownPortal = true;
};

Game_Player.prototype.disableHistoricalTownPortal = function(){
	this._enableHistoricalTownPortal = false;
};

//5.2 技能物品使用条件
SWDA_HistoricalTownPortal.TOWN_PORTAL_CAN_USE = Game_BattlerBase.prototype.canUse;
Game_BattlerBase.prototype.canUse = function(item) {
    var canUse = SWDA_HistoricalTownPortal.TOWN_PORTAL_CAN_USE.call(this, item);
    if(DataManager.isHistoricalTownPortal(item)){
    	if(!SWDA_HistoricalTownPortal.mapCanTownPortal())//地图禁止回城
    		canUse = false;
    	if(!$gamePlayer.canHistoricalTownPortal())//事件禁止回城
    		canUse = false;
    	if($gameParty.inBattle())//战斗中禁止回城
    		canUse = false;
    }
    return canUse;
};


//5.2.1 地图传送条件：没有<Can Historical Portal>标签的地图禁止传送
SWDA_HistoricalTownPortal.mapCanTownPortal = function(){
	if(!$dataMap)
		return false;
	var canTownPortal = $dataMap.meta["Can Historical Portal"];
	
	if(!canTownPortal)
		return false;

	return true;
};

//5.2.2 禁止传送状态指定：插件命令EnableHistoricalPortal与DisableHistoricalPortal
SWDA_HistoricalTownPortal.PLUGIN_COMMAND = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
	SWDA_HistoricalTownPortal.PLUGIN_COMMAND.call(this, command, args);

	if(command == 'EnableHistoricalPortal')
		$gamePlayer.enableHistoricalTownPortal();
	if(command == 'DisableHistoricalPortal')
		$gamePlayer.disableHistoricalTownPortal();
};

//=============================================================================
// 6. 移动控制：为了防止在传送过程中因移动触发事件而导致不可预知的BUG，传送过程中禁止移动
//=============================================================================
//6.1 禁止玩家移动
SWDA_HistoricalTownPortal.PLAYER_CAN_MOVE = Game_Player.prototype.canMove;
Game_Player.prototype.canMove = function() {
	var canMove = SWDA_HistoricalTownPortal.PLAYER_CAN_MOVE.call(this);
	if($gamePlayer.isHistoricalTownPortal())
		canMove = false;
	return canMove;
};

//6.2 禁止事件移动
SWDA_HistoricalTownPortal.UPDATE_EVENT_MOVEMENT	= Game_Event.prototype.updateSelfMovement;
Game_Event.prototype.updateSelfMovement = function() {
	if(!$gamePlayer.isHistoricalTownPortal())
		SWDA_HistoricalTownPortal.UPDATE_EVENT_MOVEMENT.call(this);
};
